#include "core/main.h"

namespace FruitEaterConstants
{
    static const int gridSize = 7;

    static const int playerSize = 16;

    static const int startX = 0;
    static const int startY = 0;

    static const int reward = 100;
}

void GameFruitEater::Init()
{
   _spritePlayer = _collection.AddSprite(Bitmap::LoadFile("../assets/fruitEater/player.png"), "player");
    _spriteFruit = _collection.AddSprite(Bitmap::LoadFile("../assets/fruitEater/apple.png"), "fruit");

    _collection.AddFontSprites();

    _observedIntNames.push_back("Reset");
    _observedIntNames.push_back("Score");
    _observedIntNames.push_back("Frame score");
    _observedIntNames.push_back("Player x");
    _observedIntNames.push_back("Player y");
    _observedIntNames.push_back("Frames since reset");
    _observedIntNames.push_back("dummy");

    _activeFrame.observedInts.resize(ObservedIntNames().size());
}

void GameFruitEater::NewGame()
{
    _state.score = 0;
    Reset();
}

void GameFruitEater::Reset()
{
    _state.playerX = FruitEaterConstants::startX;
    _state.playerY = FruitEaterConstants::startY;
    _state.appleX = 1 + rand() % (FruitEaterConstants::gridSize - 1);
    _state.appleY = 1 + rand() % (FruitEaterConstants::gridSize - 1);
    _state.framesSinceReset = 0;
}

void GameFruitEater::Step(ControllerState &controller)
{
    int frameScore = 0;

    if (controller.left()) {
        _state.playerX--;
    } else if (controller.right()) {
        _state.playerX++;
    } else if (controller.up()) {
        _state.playerY++;
    } else if (controller.down()) {
        _state.playerY--;
    }

    _state.playerX = Math::Bound(_state.playerX, 0, FruitEaterConstants::gridSize - 1);
    _state.playerY = Math::Bound(_state.playerY, 0, FruitEaterConstants::gridSize - 1);

    bool reset = false;
    if (_state.playerX == _state.appleX && _state.playerY == _state.appleY) {
        frameScore += FruitEaterConstants::reward;
        reset = true;
    }

    _state.score += frameScore;
    _state.framesSinceReset++;

    _activeFrame.observedInts[0] = reset ? 1 : 0;
    _activeFrame.observedInts[1] = _state.score;
    _activeFrame.observedInts[2] = frameScore;
    _activeFrame.observedInts[3] = _state.playerX;
    _activeFrame.observedInts[4] = _state.playerY;
    _activeFrame.observedInts[5] = _state.framesSinceReset;
    _activeFrame.observedInts[6] = 0;

    if (reset) {
        Reset();
    }

    MakeFrameSprites();
}

ControllerState GameFruitEater::SimpleAI()
{
    ControllerState controller;

    // Move randomly
    float num = rnd();
    if (num > 0.2f && num <= 0.4f) controller.KeyDown('a');
    else if (num > 0.4f && num <= 0.6f) controller.KeyDown('s');
    else if (num > 0.6f && num <= 0.8f) controller.KeyDown('d');
    else if (num > 0.8f) controller.KeyDown('w');

    return controller;
}

void GameFruitEater::MakeFrameSprites()
{
    _activeFrame.sprites.clear();

    // Draw the player
    int screenPlayerX = _state.playerX * FruitEaterConstants::playerSize;
    int screenPlayerY = (FruitEaterConstants::gridSize - _state.playerY - 1) * FruitEaterConstants::playerSize;
    _activeFrame.sprites.push_back(SpriteLocation(Vec2i(screenPlayerX, screenPlayerY), _spritePlayer, 0));

    // Draw the apple
    int screenAppleX = _state.appleX * FruitEaterConstants::playerSize;
    int screenAppleY = (FruitEaterConstants::gridSize - _state.appleY - 1) * FruitEaterConstants::playerSize;
    _activeFrame.sprites.push_back(SpriteLocation(Vec2i(screenAppleX, screenAppleY), _spriteFruit, 0));

    // Draw the score
    _collection.DrawText("SCORE", Vec2i(24, 1), _activeFrame.sprites, 0);
    _collection.DrawNumber(_state.score, 5, Vec2i(24, 2), _activeFrame.sprites, 0);
}